import { Global, Module, forwardRef } from "@nestjs/common";
import { UserService } from "./user.service";
import { UserController } from "./user.controller";
import { TypeOrmModule } from "@nestjs/typeorm";
import { User } from "./user.entity";
import { Profile } from "./profile.entity";
import { Roles } from "../roles/roles.entity";
import { LogsModule } from "../logs/logs.module";

/**
 * 用户模块 (UserModule)
 *
 * 这是 NestJS 中的功能模块，遵循模块化架构设计原则
 * 每个模块负责一个特定的业务领域，在这里是用户相关的功能
 *
 * 模块的作用：
 * 1. 组织相关的控制器、服务和其他提供者
 * 2. 定义模块的依赖关系和导入
 * 3. 控制依赖注入的作用域
 * 4. 实现关注点分离和代码复用
 */
// @Global() 装饰器：声明当前模块为全局模块
// 全局模块的作用：
// 1. 在其他模块中导入当前模块时，无需使用 .forFeature() 方法注册实体
// 2. 在其他模块中注入当前模块的服务时，无需使用 forwardRef() 方法
@Global()
@Module({
  /**
   * imports 数组：导入其他模块
   *
   * TypeOrmModule.forFeature([User]) 的详细解析：
   *
   * 1. 为什么需要这行代码？
   *    - NestJS 使用依赖注入容器管理所有组件
   *    - Repository 是 TypeORM 提供的数据访问层抽象
   *    - 必须先注册 Repository，才能在服务中注入使用
   *
   * 2. forFeature() 方法的作用：
   *    - 为指定的实体创建 Repository 提供者
   *    - 将 Repository 注册到当前模块的依赖注入容器中
   *    - 生成类似这样的内部提供者配置：
   *      {
   *        provide: getRepositoryToken(User),
   *        useFactory: (connection) => connection.getRepository(User),
   *        inject: [getConnectionToken()]
   *      }
   *
   * 3. 底层工作流程：
   *    a) 模块初始化时，TypeORM 解析 User 实体的元数据
   *    b) 创建 Repository<User> 的提供者定义
   *    c) 注册到模块的依赖注入容器中
   *    d) 当 UserService 请求注入时，容器提供 Repository 实例
   *
   * 4. 如果不写这行代码会怎样？
   *    - UserService 中的 @InjectRepository(User) 会抛出错误
   *    - 错误信息：找不到 Repository<User> 的提供者
   *    - 应用启动失败
   *
   * 5. 与传统 ORM 的对比：
   *    传统方式：const repo = connection.getRepository(User)
   *    NestJS 方式：通过依赖注入自动获取，无需手动管理连接
   */
  imports: [TypeOrmModule.forFeature([User, Profile, Roles]), forwardRef(() => LogsModule)],

  /**
   * providers 数组：定义模块内的服务提供者
   *
   * UserService 是业务逻辑层，负责：
   * 1. 处理用户相关的业务逻辑
   * 2. 与数据访问层 (Repository) 交互
   * 3. 数据验证和转换
   * 4. 事务管理
   *
   * 依赖注入原理：
   * - NestJS 会自动实例化 UserService
   * - 解析其构造函数的依赖 (如 Repository<User>)
   * - 从容器中获取对应的实例并注入
   */
  providers: [UserService],

  /**
   * controllers 数组：定义模块内的控制器
   *
   * UserController 是表现层，负责：
   * 1. 处理 HTTP 请求和响应
   * 2. 路由定义和参数验证
   * 3. 调用业务逻辑层 (UserService)
   * 4. 数据格式转换和错误处理
   *
   * 控制器与服务的分离体现了分层架构的设计原则：
   * Controller -> Service -> Repository -> Database
   */
  controllers: [UserController],

  /**
   * exports 数组：导出模块内的提供者供其他模块使用
   *
   * 导出 UserService 的原因：
   * 1. 其他模块 (如 LogsModule) 需要使用 UserService
   * 2. 实现模块间的服务共享和依赖注入
   * 3. 遵循 NestJS 模块化架构的最佳实践
   *
   * 如果不导出会怎样？
   * - 其他模块无法注入 UserService
   * - 会抛出 "找不到提供者" 的错误
   * - 应用启动失败
   *
   * 导出原则：
   * - 只导出需要被其他模块使用的服务
   * - 不导出仅供模块内部使用的服务
   * - 保持模块边界清晰，避免过度耦合
   */
  exports: [UserService],
})
export class UserModule {}
